package org.grapes.wine.api.client.method.impl;

import java.io.IOException;
import java.net.URL;
import java.util.Collection;
import java.util.EnumSet;
import java.util.Set;

import org.grapes.wine.api.client.exception.WineException;
import org.grapes.wine.api.client.method.IRestClientMethods;
import org.grapes.wine.api.client.param.ProfileField;
import org.grapes.wine.api.method.EWineMethod;
import org.w3c.dom.Document;
import org.w3c.dom.Node;

public abstract class WineMethods extends CallWineMethod implements
		IRestClientMethods<Document> {
	
	private String sessionKey;
	private int userId; // late initialized
	private Boolean added;

	public WineMethods(String apiKey, String sessionKey) {
		super(apiKey, sessionKey);
		this.sessionKey = sessionKey;
	}
	
	/*
	public String authGetSession(String authToken) throws WineException,
			IOException {
		Document doc = callMethod(EWineMethod.AUTH_GET_SESSION,
				new Pair<String, CharSequence>("auth_token", authToken
						.toString()));
		if (doc == null) {
			return null;
		}
		sessionKey = doc.getElementsByTagName("session_key").item(0)
				.getFirstChild().getTextContent();
		userId = Integer.parseInt(doc.getElementsByTagName("uid").item(0)
				.getFirstChild().getTextContent());
		return sessionKey;
	}

	public Document adminGetAllocation() throws WineException, IOException {
		return callMethod(EWineMethod.ADMIN_GET_ALLCATION);
	}

	public Document friends_areFriends(Collection<Integer> userIds1,
			Collection<Integer> userIds2) throws WineException, IOException {
		assert (userIds1 != null && userIds2 != null);
		assert (!userIds1.isEmpty() && !userIds2.isEmpty());
		assert (userIds1.size() == userIds2.size());

		return callMethod(
				EWineMethod.FRIENDS_ARE_FRIENDS,
				new Pair<String, CharSequence>("uids1", super.delimit(userIds1)),
				new Pair<String, CharSequence>("uids2", super.delimit(userIds2)));
	}

	public Document friendsGetFriends() throws WineException, IOException {
		Document doc = callMethod(EWineMethod.FRIENDS_GET_FRIENDS);
		return doc;
	}

	public Document friendsGet() throws WineException, IOException {
		return callMethod(EWineMethod.FRIENDS_GET);
	}

	public Document friendsGetAppUsers() throws WineException, IOException {
		return callMethod(EWineMethod.FRIENDS_GET_APP_USERS);
	}

	public Document usersGetInfo(Integer userId, EnumSet<ProfileField> fields)
			throws WineException, IOException {
		// assertions test for invalid params
		assert (userId != null);
		assert (fields != null);
		assert (!fields.isEmpty());

		return callMethod(EWineMethod.USERS_GET_INFO,
				new Pair<String, CharSequence>("uids", String.valueOf(userId)),
				new Pair<String, CharSequence>("fields", delimit(fields)));
	}

	public Document usersGetInfo(Collection<Integer> userIds,
			EnumSet<ProfileField> fields) throws WineException, IOException {
		// assertions test for invalid params
		assert (userIds != null);
		assert (fields != null);
		assert (!fields.isEmpty());

		return callMethod(EWineMethod.USERS_GET_INFO,
				new Pair<String, CharSequence>("uids", delimit(userIds)),
				new Pair<String, CharSequence>("fields", delimit(fields)));
	}

	public Document usersGetInfo(Collection<Integer> userIds,
			Set<CharSequence> fields) throws WineException, IOException {
		assert (userIds != null);
		assert (fields != null);
		assert (!fields.isEmpty());

		return callMethod(EWineMethod.USERS_GET_INFO,
				new Pair<String, CharSequence>("uids", delimit(userIds)),
				new Pair<String, CharSequence>("fields", delimit(fields)));
	}

	public int usersGetLoggedInUser() throws WineException, IOException {
		if (userId == -1) {
			Document doc = this.callMethod(EWineMethod.USERS_GET_LOGGED_IN_USER);
			if (doc == null) {
				return 0;
			}
			userId = Integer.parseInt(doc.getFirstChild().getTextContent());
		}
		return userId;
	}

	public boolean usersIsAppAdded() throws WineException, IOException {
		if (added == null) {
			added = extractBoolean(this
					.callMethod(EWineMethod.USERS_IS_APP_ADDED));
		}
		return added.booleanValue();
	}

	public boolean usersIsAppAdded(Integer userId) throws WineException,
			IOException {
		if (added == null) {
			added = extractBoolean(this.callMethod(
					EWineMethod.USERS_IS_APP_ADDED,
					new Pair<String, CharSequence>("uids", Integer
							.toString(userId))));
		}
		return added.booleanValue();
	}

	private static boolean extractBoolean(Node doc) {
		if (doc == null) {
			return false;
		}
		String content = doc.getFirstChild().getTextContent();
		return "1".equals(content);
	}
	*/
}
